package ferp.android.tasks.local;

import android.os.AsyncTask;
import ferp.android.activities.Ferp;
import ferp.android.services.IResolverService2;
import ferp.android.services.ServiceException;
import ferp.android.services.ServiceProxy;
import ferp.core.game.Game;
import ferp.core.log.Log;
import ferp.core.player.Player;

/**
 * User: olegs
 * Date: 06/02/12 17:12
 */
public class TaskResolver extends AsyncTask<Void, Void, ServiceException>
{
  public static synchronized void start(Ferp ferp, IResolverService2 service, Player mover)
  {
    // create new task instance
    instance = new TaskResolver(ferp, service, mover);
    // execute it
    instance.execute();
  }

  public static synchronized void cancel()
  {
    if (instance!= null)
    {
      TaskResolver task = instance;

      instance = null;
      task.cancel(true);
    }
  }

  public static synchronized boolean isResolving() {return instance != null;}

  public static synchronized void setGUIReady()
  {
    if (instance != null)
      instance.onSetGUIReady();
  }

  @Override
  protected ServiceException doInBackground(Void... parameters)
  {
    try
    {
      ServiceProxy.solve(service);

      synchronized (this)
      {
        while (!guiIsReady && !isCancelled())
          try
          {
            wait();
          }
          catch (InterruptedException e)
          {
            Log.error(Log.TAG, e);
          }
      }

      return null;
    }
    catch (ServiceException e)
    {
      return e;
    }
  }

  @Override
  protected void onPostExecute(ServiceException e)
  {
    if (!isCancelled() && instance != null)
    {
      instance = null;

      if (e == null)
      {
        try
        {
          ferp.onTreeReady(mover);
        }
        catch(Game.Error error)
        {
          ferp.exit((ServiceException)error.getCause());
        }
      }
      else
        ferp.exit(e);
    }
    else
      Log.debug(Log.TAG, "resolver task was cancelled");
  }

  @Override
  protected void onCancelled()
  {
    try
    {
      //ferp.getService().cancel();

      Log.debug(Log.TAG, "Resolver task has been cancelled");
    }
    catch (Exception e)
    {
      Log.error(Log.TAG, e);
    }
  }

  // single task instance at any given moment
  private static TaskResolver instance;

  // "tree ready" listener
  private final Ferp ferp;
  // resolver service
  private final IResolverService2 service;
  // mover
  private final Player mover;
  // flag that tells if GUI is ready to use a "tree"
  private boolean guiIsReady = false;

  private TaskResolver(Ferp ferp, IResolverService2 service, Player mover)
  {
    this.ferp    = ferp;
    this.service = service;
    this.mover   = mover;
  }

  private synchronized void onSetGUIReady()
  {
    instance.guiIsReady = true;
    instance.notify();
  }
}
